/* copy.c

   Copy the file named argv[1] to a new file named in argv[2].
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#ifndef BUF_SIZE /* Allow "cc -D" to override definition */
#define BUF_SIZE 1024
#endif

void errExit(char *msg) {
  perror(msg);
  exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
  int inputFd, outputFd, openFlags;
  mode_t filePerms;
  ssize_t numRead;
  char buf[BUF_SIZE];

  if (argc != 3 || strcmp(argv[1], "--help") == 0) {
    fprintf(stderr, "%s old-file new-file\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  /* Open input and output files */
  inputFd = open(argv[1], O_RDONLY);
  if (inputFd == -1) {
    fprintf(stderr, "opening file %s: %s\n", argv[1], strerror(errno));
    exit(EXIT_FAILURE);
  }

  openFlags = O_CREAT | O_WRONLY | O_TRUNC;
  filePerms =
      S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /* rw-rw-rw- */
  outputFd = open(argv[2], openFlags, filePerms);
  if (outputFd == -1) {
    fprintf(stderr, "opening file %s: %s\n", argv[2], strerror(errno));
    exit(EXIT_FAILURE);
  }

  /* Transfer data until we encounter end of input or an error */
  while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0) {
    if (write(outputFd, buf, numRead) != numRead) {
      fprintf(stderr, "write() returned error or partial write occurred");
      exit(EXIT_FAILURE);
    }
  }

  if (numRead == -1) {
    errExit("read");
  }

  if (close(inputFd) == -1) {
    errExit("close input");
  }
  if (close(outputFd) == -1) {
    errExit("close output");
  }

  exit(EXIT_SUCCESS);
}

